﻿using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json;

namespace XJay.Scheduler.Extend
{
    /// <summary>
    /// 自定义授权处理
    /// </summary>
    public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
    {
        private readonly IConfiguration _configuration;

        public PermissionHandler(IConfiguration configuration)
        {
            this._configuration = configuration;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            if (context.Resource is HttpContext httpContext)
            {
                var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
                var token = httpContext.Request.Headers.Authorization.ToString();

                if (!token.StartsWith(JwtBearerDefaults.AuthenticationScheme)) context.Fail();

                token = token.Split(" ").LastOrDefault();
                if (token == null) context.Fail();

                Info info = GetDecodingToken(token);
                if (info.IsAuthor && info.Role == 1) context.Succeed(requirement); // 显式的声明验证成功
            }
            else context.Fail();
            return Task.CompletedTask;
        }
        /// <summary>
        /// 解码token
        /// </summary>
        /// <param name="strToken">token字符串</param>
        /// <returns>json内容</returns>
        /// <exception cref="ArgumentNullException">strToken 为 null、空和由空白字符组成。</exception>
        public Info GetDecodingToken(string strToken)
        {
            Info InfoModel = new Info();
            if (string.IsNullOrWhiteSpace(strToken))
                return InfoModel;

            try
            {
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);

                string json = decoder.Decode(strToken, _configuration["JWT:SecretKey"], true);
                InfoModel = JsonConvert.DeserializeObject<Info>(json);
                InfoModel.IsAuthor = true;
            }
            catch (Exception ex)
            {
                InfoModel.IsAuthor = false;
            }

            return InfoModel;
        }
    }

    /// <summary>
    /// 用户认证信息必要参数类
    /// </summary>
    public class PermissionRequirement : IAuthorizationRequirement
    {


    }
    public class Info
    {
        public bool IsAuthor { get; set; } = false;
        /// <summary>
        /// 用户所属角色
        /// </summary>
        public int Role { get; set; }
    }
}

